{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "8e169a83",
   "metadata": {},
   "source": [
    "# The `ToDynare` notebook  <a id=\"ToDynare\"></a>[<font size=1>(back to `Main.ipynb`)</font>](./Main.ipynb)\n",
    "\n",
    "This notebook contains the function that saves the truncated Ramsey allocation on a `mat` file to be used in [Dynare](https://www.dynare.org/). This function is [`Write_Dynare`](#Write_Dynare).\n",
    "\n",
    "There is a technical difficulty in the link between Julia and Matlab/Octave. Matlab/Octave is not as flexible as Julia in the encoding of variables. Hence, all fancy unicode variables (e.g., `β`, `α`, `δ`, `γ`) need to be converted to Matlab/Octave legit variables (with letters, digits and underscore: typically here, `beta`, `alpha`, `delta`, `gamma`). This is why we need specific structures, to perform this transformation of variable names. All these structures are named as the original structure suffixed by `_Dynare`. For instance, we have `Economy_Dynare` for `Economy`. We also build constructors that precisely make the bridge between the two structures. In our example, we have `Economy_Dynare(economy::Economy)` that creates an instance of `Economy_Dynare` based on the instance `economy` of the struct `Economy`. \n",
    "\n",
    "### The notebook is organized as follows:\n",
    "* the [`Economy_Dynare`](#Economy_Dynare) structure;\n",
    "* the [`TruncatedAllocation_Dynare`](#TruncatedAllocation_Dynare) structure;\n",
    "* the [`Ramsey_Dynare`](#Ramsey_Dynare) structure;\n",
    "* the [`Write_Dynare`](#Write_Dynare) function.\n",
    "\n",
    "All main structures can be found in [`Structures.ipynb`](./Structures.ipynb)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "67725922",
   "metadata": {},
   "source": [
    "## The `Economy_Dynare` structure <a id=\"Economy_Dynare\"></a>[<font size=1>(back to menu)</font>](#ToDynare)\n",
    "\n",
    "As explained above, there is a unique structure with its associated constructor:\n",
    "* `Economy_Dynare` with a constructor using `Economy` as input."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7c5697b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "mutable struct Economy_Dynare{T<:Real,I<:Int64}\n",
    "    beta::T\n",
    "    alpha::T\n",
    "    delta::T\n",
    "    sigma::T\n",
    "    chi::T\n",
    "    phi::T\n",
    "    kappa::T\n",
    "    tau::T\n",
    "    tauk::T\n",
    "    tauc::T\n",
    "    Tt::T\n",
    "    \n",
    "    na    ::I # number of grid points\n",
    "    a_min ::T         # min asset holdings\n",
    "    aGrid ::Vector{T} # grid for asset choices\n",
    "\n",
    "    #=\n",
    "        *** productivity process ***\n",
    "    =#\n",
    "    ny    ::I         #number of states\n",
    "    ys    ::Vector{T} #productivity states    (States)\n",
    "    Piy    ::Matrix{T} #Transition matrix (under vectorial format) (Transv)\n",
    "    Sy    ::Vector{T} #distribution ver y size is ns (disty)\n",
    "    #yvect ::Array{T,1} #vector of y size is ns*na\n",
    "end\n",
    "function Economy_Dynare(economy::Economy)\n",
    "    @unpack β,α,δ,σ,χ,φ,κ,τ,τk,Tt,        \n",
    "        na,a_min,a_max,aGrid,\n",
    "        ny,ys,Πy,Sy = economy\n",
    "        τc = 0.0\n",
    "    Economy_Dynare(β,α,δ,σ,χ,φ,κ,τ,τk,τc,Tt,na,a_min,aGrid,ny,ys,Πy,Sy)\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae5522de",
   "metadata": {},
   "source": [
    "## The `TruncatedAllocation_Dynare` structure <a id=\"TruncatedAllocation_Dynare\"></a>[<font size=1>(back to menu)</font>](#ToDynare)\n",
    "\n",
    "There are three structures with their associated constructors:\n",
    "* `TruncatedAllocation_Dynare` with a constructor using `TruncatedAllocation` as input;\n",
    "* `xsis_struct_Dynare` with a constructor using `ξs_struct` as input;\n",
    "* `TruncatedModel_Dynare` with a constructor using `TruncatedModel` as input."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "147e557b",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct TruncatedAllocation_Dynare{I<:Integer,T<:Real}\n",
    "    S_h::Vector{T}       # size of truncated histories\n",
    "    Pi_h::Matrix{T}      # transition matrix for histories\n",
    "    y0_h::Vector{T}      # current productivity levels\n",
    "    a_beg_h::Vector{T}   # beginning-of-period wealth per history and per capita\n",
    "    a_end_h::Vector{T}   # end-of-period wealth per history and per capita\n",
    "    c_h::Vector{T}       # consumption per history and per capita\n",
    "    l_h::Vector{T}       # labor supply per history and per capita\n",
    "    ly_tau_h::Vector{T}    # (l y)^τ\n",
    "    u_h::Vector{T}       # utility of consumption per history and per capita\n",
    "    uc_h::Vector{T}      # marginal utility of consumption per history and per capita\n",
    "    ucc_h::Vector{T}     # second-order derivative of utility of consumption per history and per capita\n",
    "    #v_h::Vector{T}       # utility of labor per history and per capita\n",
    "    #vl_h::Vector{T}      # marginal utility of labor per history and per capita\n",
    "    resid_E_h::Vector{T} # Euler Lagrange multiplier at the history level\n",
    "    nb_cc_h::I           # nb of credit constrained histories\n",
    "    ind_cc_h::Vector{I}  # indices of credit constrained histories\n",
    "end\n",
    "\n",
    "struct xsis_struct_Dynare{T<:Real}\n",
    "    xsiu0::Vector{T}\n",
    "    xsiu1::Vector{T}\n",
    "    xsiu2::Vector{T}\n",
    "    xsiuE::Vector{T}\n",
    "    xsiy ::Vector{T}\n",
    "    xsiv0::Vector{T}\n",
    "    xsiv1::Vector{T}\n",
    "end  \n",
    "\n",
    "struct TruncatedModel_Dynare{I<:Integer,T<:Real}\n",
    "    N::I\n",
    "    refiNs::Vector{I}\n",
    "    Ntot::I\n",
    "    ind_h::Vector{I}\n",
    "    truncatedAllocation::TruncatedAllocation_Dynare{I,T}\n",
    "    xsis::xsis_struct_Dynare{T}\n",
    "end\n",
    "function TruncatedAllocation_Dynare(truncatedAllocation::TruncatedAllocation)\n",
    "    @unpack S_h,Π_h,y0_h,a_beg_h,a_end_h,c_h,l_h,ly_τ_h,u_h,u′_h,u′′_h,\n",
    "            v_h,v′_h,resid_E_h, nb_cc_h,ind_cc_h = truncatedAllocation\n",
    "    TruncatedAllocation_Dynare(S_h,Matrix(Π_h),y0_h,a_beg_h,a_end_h,c_h,l_h,ly_τ_h,u_h,u′_h,u′′_h,\n",
    "            resid_E_h, nb_cc_h,ind_cc_h)    \n",
    "end\n",
    "function xsis_struct_Dynare(ξs::ξs_struct)\n",
    "    @unpack ξu0,ξu1,ξu2,ξuE,ξy,ξv0,ξv1 = ξs\n",
    "    xsis_struct_Dynare(ξu0,ξu1,ξu2,ξuE,ξy,ξv0,ξv1)\n",
    "end\n",
    "function TruncatedModel_Dynare(truncatedModel::TruncatedModel)\n",
    "    @unpack N,refiNs,Ntot,ind_h,truncatedAllocation,ξs = truncatedModel\n",
    "    TruncatedModel_Dynare(N,refiNs,Ntot,ind_h,\n",
    "        TruncatedAllocation_Dynare(truncatedAllocation),xsis_struct_Dynare(ξs))\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "306b0d15",
   "metadata": {},
   "source": [
    "## The `Ramsey_Dynare` structure <a id=\"Ramsey_Dynare\"></a>[<font size=1>(back to menu)</font>](#ToDynare)\n",
    "\n",
    "There are also three structures with their associated constructors:\n",
    "* `Weights_Dynare` with a constructor using `Weights` as input;\n",
    "* `LagrangeMult_Dynare` with a constructor using `LagrangeMult` as input;\n",
    "* `Ramsey_Dynare` with a constructor using `Ramsey` as input."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "558a5955",
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Weights_Dynare{T<:Real}\n",
    "    omega         ::Vector{T} \n",
    "    omegab        ::Vector{T}\n",
    "    omega_h       ::Vector{T}\n",
    "    omegab_h      ::Vector{T}\n",
    "    omega_param   ::Vector{T} \n",
    "    omegab_param  ::Vector{T}\n",
    "    omega_param_h ::Vector{T} \n",
    "    omegab_param_h::Vector{T}\n",
    "end \n",
    "struct LagrangeMult_Dynare{T<:Real}\n",
    "    lambdac ::Vector{T}\n",
    "    lambdact::Vector{T}\n",
    "    lambdacb::Vector{T}\n",
    "    lambdal ::Vector{T}\n",
    "    lambdalt::Vector{T}\n",
    "    lambdalb::Vector{T}\n",
    "    mu      ::T\n",
    "    psi     ::Vector{T}\n",
    "    psib    ::Vector{T}\n",
    "end \n",
    "struct Ramsey_Dynare{I<:Integer,T<:Real}\n",
    "    weights       ::Weights_Dynare{T}\n",
    "    lagrangeMult  ::LagrangeMult_Dynare{T}\n",
    "    truncatedModel::TruncatedModel_Dynare{I,T}\n",
    "    l::T\n",
    "end\n",
    "function Weights_Dynare(weights::Weights)\n",
    "    @unpack ω,ωb,ω_h,ωb_h,ω_param,ωb_param,ω_param_h,ωb_param_h = weights\n",
    "    Weights_Dynare(ω,ωb,ω_h,ωb_h,ω_param,ωb_param,ω_param_h,ωb_param_h)\n",
    "end\n",
    "function LagrangeMult_Dynare(lagrangeMult::LagrangeMult)\n",
    "    @unpack λc,λct,λcb,λl,λlt,λlb,μ,ψ,ψb = lagrangeMult\n",
    "    LagrangeMult_Dynare(λc,λct,λcb,λl,λlt,λlb,μ,ψ,ψb)\n",
    "end\n",
    "function Ramsey_Dynare(ramsey::Ramsey)\n",
    "    @unpack weights,lagrangeMult,truncatedModel,l = ramsey\n",
    "    Ramsey_Dynare(Weights_Dynare(weights),\n",
    "                  LagrangeMult_Dynare(lagrangeMult),\n",
    "                  TruncatedModel_Dynare(truncatedModel),l)\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "44d2d1fb",
   "metadata": {},
   "source": [
    "## The `write_Dynare` function <a id=\"Write_Dynare\"></a>[<font size=1>(back to menu)</font>](#ToDynare)\n",
    "\n",
    "The function is invoked by: \n",
    "> `write_Dynare(filename::String,ramsey::Ramsey,solution::AiyagariSolution,economy::Economy)`,\n",
    "\n",
    "where:\n",
    "* `filename` is the output filename (necessarily as a `mat` file);\n",
    "* the truncated Ramsey model, `ramsey`;\n",
    "* the Aiyagari solution, `solution`;\n",
    "* the economy parameters, `economy`.\n",
    "\n",
    "The function returns `nothing` but writes a file named `filename` that can be used by Dynare to simulate the model with aggregate aggregate shocks via perturbation method. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "534d6e41",
   "metadata": {},
   "outputs": [],
   "source": [
    "function write_Dynare(filename::String,ramsey::Ramsey,solution::AiyagariSolution,economy::Economy)::Nothing\n",
    "    \n",
    "    filename_elts = split(filename,\".\")\n",
    "    if (length(filename_elts) == 1) \n",
    "        filename_ = filename*\".mat\"\n",
    "    elseif (length(filename_elts) > 2) \n",
    "        filename_ = join(filename_elts[1:end-1],\"-\")*\".mat\"\n",
    "    elseif (filename[end]) != \"mat\"\n",
    "        filename_ = join(filename_elts[1:end-1],\"-\")*\".mat\"\n",
    "    else\n",
    "        filename_ = filename\n",
    "    end\n",
    "        \n",
    "    economy_Dynare = Economy_Dynare(economy)\n",
    "    ramsey_Dynare  = Ramsey_Dynare(ramsey)\n",
    "    \n",
    "    file = matopen(filename, \"w\")\n",
    "    write(file, \"Ramsey\", ramsey_Dynare) \n",
    "    write(file, \"eco\", economy_Dynare)\n",
    "    write(file, \"solution\", solution)\n",
    "    close(file)\n",
    "end"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 1.10.5",
   "language": "julia",
   "name": "julia-1.10"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.10.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
